// ===============================================
// refresher_gif_header
//
// Create by Will on 14/9/2023 13:56
// Copyright Will rights reserved.
// ===============================================

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'
    hide RefreshIndicator, RefreshIndicatorState;
import 'package:pull_to_refresh/pull_to_refresh.dart';

class RefreshHeader extends RefreshIndicator {
  const RefreshHeader({super.key})
      : super(height: 80, refreshStyle: RefreshStyle.Follow);

  @override
  State<StatefulWidget> createState() {
    return GifHeaderState();
  }
}

class GifHeaderState extends RefreshIndicatorState<RefreshHeader>
    with SingleTickerProviderStateMixin {
  @override
  Future<void> endRefresh() {
    return Future<void>.delayed(const Duration(microseconds: 500), () {});
  }

  @override
  Widget buildContent(BuildContext context, RefreshStatus mode) {
    Widget body = Container(
      padding: const EdgeInsets.all(6),
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(15),
      ),
      width: 30,
      height: 30,
      child: const CircularProgressIndicator(
        backgroundColor: Colors.white70,
        strokeWidth: 3,
      ),
    );
    switch (mode) {
      case RefreshStatus.idle:
        body = Container(
          padding: const EdgeInsets.all(6),
          decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(15),
          ),
          width: 30,
          height: 30,
          child: const CircularProgressIndicator(
            backgroundColor: Colors.white70,
            strokeWidth: 3,
          ),
        );
        break;
      case RefreshStatus.canRefresh:
        break;
      case RefreshStatus.refreshing:
        body = Container(
          padding: const EdgeInsets.all(6),
          decoration: BoxDecoration(
            borderRadius: BorderRadius.circular(15),
          ),
          width: 30,
          height: 30,
          child: const CircularProgressIndicator(
            backgroundColor: Colors.white70,
            strokeWidth: 3,
          ),
        );
        break;
      case RefreshStatus.completed:
        // body = Container(
        //   padding: const EdgeInsets.symmetric(horizontal: 7, vertical: 10),
        //   decoration: BoxDecoration(
        //     color: AppStyle.btnBackgroundColor,
        //     borderRadius: BorderRadius.circular(10),
        //   ),
        //   child: Text(
        //     '${AppUtils.txt('app_refresh_add')}20${AppUtils.txt('app_refresh_end')}',
        //     style: AppStyle.secondaryTextStyle14,
        //   ),
        // );
        break;
      case RefreshStatus.failed:
        break;
      case RefreshStatus.canTwoLevel:
        break;
      case RefreshStatus.twoLevelOpening:
        break;
      case RefreshStatus.twoLeveling:
        break;
      case RefreshStatus.twoLevelClosing:
        break;
    }

    return Container(
      margin: const EdgeInsets.symmetric(vertical: 15),
      child: Center(
        child: body,
      ),
    );
  }
}

class RefreshFooter extends StatefulWidget {
  const RefreshFooter({
    super.key,
    this.footerHeight,
    this.footerTextColor,
  });

  final double? footerHeight;
  final Color? footerTextColor;
  @override
  State<StatefulWidget> createState() {
    return _RefreshFooterState();
  }
}

class _RefreshFooterState extends State<RefreshFooter>
    with SingleTickerProviderStateMixin {
  @override
  Widget build(BuildContext context) {
    return CustomFooter(
      height: widget.footerHeight ?? 60.0,
      builder: (context, mode) {
        Widget body;
        if (mode == LoadStatus.idle) {
          body = const Text(
            'app_refresh_idle',
          );
        } else if (mode == LoadStatus.loading) {
          body = const CupertinoActivityIndicator();
        } else if (mode == LoadStatus.failed) {
          body = const Text(
            'app_refresh_failed',
          );
        } else if (mode == LoadStatus.canLoading) {
          body = const Text(
            'app_refresh_canLoading',
          );
        } else {
          body = const Text(
            'app_refresh_no_date',
          );
        }
        return Container(
          padding: const EdgeInsets.symmetric(vertical: 8.0),
          child: Center(child: body),
        );
      },
      // loadStyle: LoadStyle.ShowWhenLoading,
    );
  }
}

///
// // How much the scroll's drag gesture can overshoot the RefreshIndicator's
// // displacement; max displacement = _kDragSizeFactorLimit * displacement.
// const double _kDragSizeFactorLimit = 1.5;
//
// /// mostly use flutter inner's RefreshIndicator
// class MaterialClassicHeader extends RefreshIndicator {
//   const MaterialClassicHeader({
//     super.key,
//     super.height = 80.0,
//     this.semanticsLabel,
//     this.semanticsValue,
//     this.color,
//     super.offset,
//     this.distance = 50.0,
//     this.backgroundColor,
//   }) : super(
//           refreshStyle: RefreshStyle.Front,
//         );
//
//   /// see flutter RefreshIndicator documents,the meaning same with that
//   final String? semanticsLabel;
//
//   /// see flutter RefreshIndicator documents,the meaning same with that
//   final String? semanticsValue;
//
//   /// see flutter RefreshIndicator documents,the meaning same with that
//   final Color? color;
//
//   /// Distance from the top when refreshing
//   final double distance;
//
//   /// see flutter RefreshIndicator documents,the meaning same with that
//   final Color? backgroundColor;
//
//   @override
//   State<StatefulWidget> createState() {
//     return _MaterialClassicHeaderState();
//   }
// }
//
// class _MaterialClassicHeaderState
//     extends RefreshIndicatorState<MaterialClassicHeader>
//     with TickerProviderStateMixin {
//   late ScrollPosition? _position;
//   Animation<Offset>? _positionFactor;
//   Animation<Color?>? _valueColor;
//   late AnimationController _scaleFactor;
//   late AnimationController _positionController;
//   late AnimationController _valueAni;
//
//   @override
//   void initState() {
//     _valueAni = AnimationController(
//         vsync: this, value: 0.0, duration: const Duration(milliseconds: 500));
//     _valueAni.addListener(() {
//       // frequently setState will decline the performance
//       if (mounted && _position!.pixels <= 0) {
//         setState(() {});
//       }
//     });
//     _positionController = AnimationController(
//         vsync: this, duration: const Duration(milliseconds: 300));
//     _scaleFactor = AnimationController(
//         vsync: this, value: 1.0, duration: const Duration(milliseconds: 300));
//     _positionFactor = _positionController.drive(Tween<Offset>(
//         begin: const Offset(0.0, -1.0),
//         end: Offset(0.0, widget.height / 44.0)));
//     super.initState();
//   }
//
//   @override
//   void didUpdateWidget(covariant MaterialClassicHeader oldWidget) {
//     _position = Scrollable.of(context).position;
//     super.didUpdateWidget(oldWidget);
//   }
//
//   @override
//   Widget buildContent(BuildContext context, RefreshStatus? mode) {
//     return _buildIndicator(widget.backgroundColor ?? Colors.white);
//   }
//
//   Widget _buildIndicator(Color outerColor) {
//     return SlideTransition(
//       position: _positionFactor!,
//       child: ScaleTransition(
//         scale: _scaleFactor,
//         child: Align(
//           alignment: Alignment.topCenter,
//           child: RefreshProgressIndicator(
//             semanticsLabel: widget.semanticsLabel ??
//                 MaterialLocalizations.of(context).refreshIndicatorSemanticLabel,
//             semanticsValue: widget.semanticsValue,
//             value: floating ? null : _valueAni.value,
//             valueColor: _valueColor,
//             backgroundColor: outerColor,
//           ),
//         ),
//       ),
//     );
//   }
//
//   @override
//   void onOffsetChange(double offset) {
//     if (!floating) {
//       _valueAni.value = offset / configuration!.headerTriggerDistance;
//       _positionController.value = offset / configuration!.headerTriggerDistance;
//     }
//   }
//
//   @override
//   void onModeChange(RefreshStatus? mode) {
//     if (mode == RefreshStatus.refreshing) {
//       _positionController.value = widget.distance / widget.height;
//       _scaleFactor.value = 1;
//     }
//     super.onModeChange(mode);
//   }
//
//   @override
//   void resetValue() {
//     _scaleFactor.value = 1.0;
//     _positionController.value = 0.0;
//     _valueAni.value = 0.0;
//     super.resetValue();
//   }
//
//   @override
//   void didChangeDependencies() {
//     final ThemeData theme = Theme.of(context);
//     _position = Scrollable.of(context).position;
//     _valueColor = _positionController.drive(
//       ColorTween(
//         begin: (widget.color ?? theme.primaryColor).withOpacity(0.0),
//         end: (widget.color ?? theme.primaryColor).withOpacity(1.0),
//       ).chain(
//           CurveTween(curve: const Interval(0.0, 1.0 / _kDragSizeFactorLimit))),
//     );
//     super.didChangeDependencies();
//   }
//
//   @override
//   Future<void> readyToRefresh() {
//     return _positionController.animateTo(widget.distance / widget.height);
//   }
//
//   @override
//   Future<void> endRefresh() {
//     return _scaleFactor.animateTo(0.0);
//   }
//
//   @override
//   void dispose() {
//     _valueAni.dispose();
//     _scaleFactor.dispose();
//     _positionController.dispose();
//     super.dispose();
//   }
// }
//
// /// attach the waterdrop effect to [MaterialClassicHeader]
// class WaterDropMaterialHeader extends MaterialClassicHeader {
//   const WaterDropMaterialHeader({
//     super.key,
//     super.semanticsLabel,
//     super.distance = 60.0,
//     super.offset,
//     super.semanticsValue,
//     Color super.color = Colors.white,
//     super.backgroundColor,
//   }) : super(height: 80.0);
//
//   @override
//   State<StatefulWidget> createState() {
//     return _WaterDropMaterialHeaderState();
//   }
// }
//
// class _WaterDropMaterialHeaderState extends _MaterialClassicHeaderState {
//   AnimationController? _bezierController;
//   bool _showWater = false;
//
//   @override
//   void initState() {
//     super.initState();
//     _bezierController = AnimationController(
//         vsync: this,
//         duration: const Duration(milliseconds: 500),
//         upperBound: 1.5,
//         value: 0.0);
//     _positionController = AnimationController(
//         vsync: this, duration: const Duration(milliseconds: 300), value: 0.0);
//     _positionFactor = _positionController.drive(Tween<Offset>(
//         begin: const Offset(0.0, -0.5), end: const Offset(0.0, 1.5)));
//   }
//
//   @override
//   void didChangeDependencies() {
//     super.didChangeDependencies();
//     final ThemeData theme = Theme.of(context);
//     _valueColor = _positionController.drive(
//       ColorTween(
//         begin: (widget.color ?? theme.primaryColor).withOpacity(0.0),
//         end: (widget.color ?? theme.primaryColor).withOpacity(1.0),
//       ).chain(
//           CurveTween(curve: const Interval(0.0, 1.0 / _kDragSizeFactorLimit))),
//     );
//   }
//
//   @override
//   Future<void> readyToRefresh() {
//     _bezierController!.value = 1.01;
//     _showWater = true;
//     _bezierController!.animateTo(1.5,
//         curve: Curves.bounceOut, duration: const Duration(milliseconds: 550));
//     return _positionController
//         .animateTo(widget.distance / widget.height,
//             curve: Curves.bounceOut,
//             duration: const Duration(milliseconds: 550))
//         .then((_) {
//       _showWater = false;
//     });
//   }
//
//   @override
//   Future<void> endRefresh() {
//     _showWater = false;
//     return super.endRefresh();
//   }
//
//   @override
//   void resetValue() {
//     _bezierController!.reset();
//     super.resetValue();
//   }
//
//   @override
//   void dispose() {
//     _bezierController!.dispose();
//     super.dispose();
//   }
//
//   @override
//   void onOffsetChange(double offset) {
//     offset = offset > 80.0 ? 80.0 : offset;
//
//     if (!floating) {
//       _bezierController!.value = offset / configuration!.headerTriggerDistance;
//       _valueAni.value = _bezierController!.value;
//       _positionController.value = _bezierController!.value * 0.3;
//       _scaleFactor.value =
//           offset < 40.0 ? 0.0 : (_bezierController!.value - 0.5) * 2 + 0.5;
//     }
//   }
//
//   @override
//   Widget buildContent(BuildContext context, RefreshStatus? mode) {
//     return SizedBox(
//       height: 100.0,
//       child: Stack(
//         children: <Widget>[
//           CustomPaint(
//             painter: _BezierPainter(
//                 listener: _bezierController,
//                 color:
//                     widget.backgroundColor ?? Theme.of(context).primaryColor),
//             child: Container(),
//           ),
//           CustomPaint(
//             painter: _showWater
//                 ? _WaterPainter(
//                     ratio: widget.distance / widget.height,
//                     color: widget.backgroundColor ??
//                         Theme.of(context).primaryColor,
//                     listener: _positionFactor)
//                 : null,
//             child: _buildIndicator(
//                 widget.backgroundColor ?? Theme.of(context).primaryColor),
//           )
//         ],
//       ),
//     );
//   }
// }
//
// class _WaterPainter extends CustomPainter {
//   _WaterPainter({this.color, this.listener, this.ratio})
//       : super(repaint: listener);
//   final Color? color;
//   final Animation<Offset>? listener;
//
//   Offset get offset => listener!.value;
//   final double? ratio;
//
//   @override
//   void paint(Canvas canvas, Size size) {
//     final Paint paint = Paint()..color;
//     final Path path = Path()
//       ..moveTo(size.width / 2 - 20.0, offset.dy * 100.0 + 20.0)
//       ..conicTo(
//           size.width / 2,
//           offset.dy * 100.0 - 70.0 * (ratio! - offset.dy),
//           size.width / 2 + 20.0,
//           offset.dy * 100.0 + 20.0,
//           10.0 * (ratio! - offset.dy));
//     canvas.drawPath(path, paint);
//   }
//
//   @override
//   bool shouldRepaint(_WaterPainter oldDelegate) {
//     return this != oldDelegate || offset != oldDelegate.offset;
//   }
// }
//
// class _BezierPainter extends CustomPainter {
//   _BezierPainter({this.listener, this.color}) : super(repaint: listener);
//   final AnimationController? listener;
//   final Color? color;
//
//   double get value => listener!.value;
//
//   @override
//   void paint(Canvas canvas, Size size) {
//     final double middleX = size.width / 2;
//     final Paint paint = Paint()..color;
//     if (value < 0.5) {
//       final Path path = Path()
//         ..moveTo(0.0, 0.0)
//         ..quadraticBezierTo(middleX, 70.0 * value, size.width, 0.0);
//       canvas.drawPath(path, paint);
//     } else if (value <= 1.0) {
//       final Path path = Path();
//       final double offsetY = 60.0 * (value - 0.5) + 20.0;
//       path
//         ..moveTo(0.0, 0.0)
//         ..quadraticBezierTo(middleX + 40.0 * (value - 0.5), 40.0 - 40.0 * value,
//             middleX - 10.0, offsetY)
//         ..lineTo(middleX + 10.0, offsetY)
//         ..quadraticBezierTo(middleX - 40.0 * (value - 0.5), 40.0 - 40.0 * value,
//             size.width, 0.0)
//         ..moveTo(size.width, 0.0)
//         ..lineTo(0.0, 0.0);
//       canvas.drawPath(path, paint);
//     } else {
//       final Path path = Path()
//         ..moveTo(0.0, 0.0)
//         ..conicTo(middleX, 60.0 * (1.5 - value), size.width, 0.0, 5.0);
//       canvas.drawPath(path, paint);
//     }
//   }
//
//   @override
//   bool shouldRepaint(_BezierPainter oldDelegate) {
//     return this != oldDelegate || oldDelegate.value != value;
//   }
// }
